package ssq.gamest.toolchain;

import com.google.common.base.Objects;
import java.io.File;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Functions.Function0;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
import ssq.gamest.toolchain.GeneratorSettings;
import ssq.gamest.toolchain.ReflectTreeBuilder;
import ssq.gamest.toolchain.RuleParser;
import ssq.utils.FileUtils;

@SuppressWarnings("all")
public class PokerPatternDetecterGenerator {
  private final GeneratorSettings settings;
  
  private final RuleParser ruleParser = new Function0<RuleParser>() {
    public RuleParser apply() {
      try {
        RuleParser _ruleParser = new RuleParser();
        return _ruleParser;
      } catch (Throwable _e) {
        throw Exceptions.sneakyThrow(_e);
      }
    }
  }.apply();
  
  public static String matchTopTemplate(final String gameName, final String patternName, final String body, final String suffix, final String leastCards) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("package ssq.gamest.game.");
    _builder.append(gameName, "");
    _builder.append(".patterns;");
    _builder.newLineIfNotEmpty();
    _builder.newLine();
    _builder.append("import java.util.Arrays;");
    _builder.newLine();
    _builder.append("import java.util.LinkedList;");
    _builder.newLine();
    _builder.append("import java.util.List;");
    _builder.newLine();
    _builder.append("import java.util.Vector;");
    _builder.newLine();
    _builder.append("import java.util.Stack;");
    _builder.newLine();
    _builder.newLine();
    _builder.append("import ssq.utils.Pair;");
    _builder.newLine();
    _builder.newLine();
    _builder.append("import ssq.gamest.game.Poker;");
    _builder.newLine();
    _builder.append("import ssq.gamest.game.Color;");
    _builder.newLine();
    _builder.append("import ssq.gamest.game.PokerCardGroup;");
    _builder.newLine();
    _builder.append("import ssq.gamest.game.PokerOrderSettings;");
    _builder.newLine();
    _builder.append("import ssq.gamest.game.PokerPattern;");
    _builder.newLine();
    _builder.newLine();
    _builder.append("/**");
    _builder.newLine();
    _builder.append("* Subclass of PokerPattern. Auto-generated by Gamest-ToolChain.");
    _builder.newLine();
    _builder.append("*/");
    _builder.newLine();
    _builder.append("public class ");
    _builder.append(patternName, "");
    _builder.append(" extends PokerPattern");
    _builder.newLineIfNotEmpty();
    _builder.append("{");
    _builder.newLine();
    _builder.append("\t");
    _builder.append("public static final int leastCards = ");
    _builder.append(leastCards, "\t");
    _builder.append(";");
    _builder.newLineIfNotEmpty();
    _builder.append("    ");
    _builder.append("/**");
    _builder.newLine();
    _builder.append("     ");
    _builder.append("* 所有的term并联, 前边的优先采用.");
    _builder.newLine();
    _builder.append("     ");
    _builder.append("*/");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("@Override");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("public List<Pair<PokerPattern, PokerCardGroup>> match(PokerCardGroup pokerCardGroup, boolean partial, boolean first)");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("{");
    _builder.newLine();
    _builder.append("        ");
    _builder.append(body, "        ");
    _builder.newLineIfNotEmpty();
    _builder.append("        ");
    _builder.append("return emptyResult;");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("}");
    _builder.newLine();
    _builder.append("    ");
    _builder.newLine();
    _builder.append("    ");
    _builder.append(suffix, "    ");
    _builder.newLineIfNotEmpty();
    _builder.append("}");
    return _builder.toString();
  }
  
  public static String matchSubTemplate(final String suffix, final String body) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("public List<Pair<PokerPattern, PokerCardGroup>> match");
    _builder.append(suffix, "");
    _builder.append("(PokerCardGroup pokerCardGroup, boolean partial, boolean first)");
    _builder.newLineIfNotEmpty();
    _builder.append("{");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("try");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("{");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("PokerOrderSettings settings = pokerCardGroup.game.settings;");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("//记录匹配后剩余的牌");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("Stack<PokerCardGroup> searchStack = new Stack<PokerCardGroup>();");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("PokerCardGroup tmp = pokerCardGroup;");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("List<Pair<PokerPattern, PokerCardGroup>> result = new LinkedList<Pair<PokerPattern, PokerCardGroup>>();");
    _builder.newLine();
    _builder.newLine();
    _builder.append("        ");
    _builder.append(body, "        ");
    _builder.newLineIfNotEmpty();
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return result;");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("}");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("catch (Exception e)");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("{");
    _builder.newLine();
    _builder.append("        ");
    _builder.append("return emptyResult;");
    _builder.newLine();
    _builder.append("    ");
    _builder.append("}");
    _builder.newLine();
    _builder.append("}");
    return _builder.toString();
  }
  
  public static String constructorTemplate(final String patternName, final List<String> assertEquals) {
    String _xblockexpression = null;
    {
      StringBuilder sb = new StringBuilder();
      StringBuilder arguments = new StringBuilder();
      for (final String str : assertEquals) {
        {
          String _xifexpression = null;
          boolean _contains = str.contains("Color");
          if (_contains) {
            _xifexpression = "Color ";
          } else {
            _xifexpression = "int ";
          }
          String type = _xifexpression;
          boolean _contains_1 = assertEquals.contains(str);
          if (_contains_1) {
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("public ");
            _builder.append(type, "");
            StringBuilder _append = sb.append(_builder);
            StringBuilder _append_1 = _append.append(str);
            _append_1.append(";\n");
          }
          StringBuilder _append_2 = arguments.append(", ");
          StringBuilder _append_3 = _append_2.append(type);
          _append_3.append(str);
        }
      }
      StringConcatenation _builder = new StringConcatenation();
      _builder.append("public ");
      _builder.append(patternName, "");
      _builder.append("(){}");
      _builder.newLineIfNotEmpty();
      _builder.newLine();
      _builder.append("public ");
      _builder.append(patternName, "");
      _builder.append("(Poker game");
      _builder.append(arguments, "");
      _builder.append(", int sumOfCards, List<Integer> weights)");
      _builder.newLineIfNotEmpty();
      _builder.append("{");
      _builder.newLine();
      _builder.append("\t");
      _builder.append("super(game, sumOfCards, weights);");
      _builder.newLine();
      {
        for(final String argu : assertEquals) {
          _builder.append("\t");
          _builder.append("this.");
          _builder.append(argu, "\t");
          _builder.append(" = ");
          _builder.append(argu, "\t");
          _builder.append(";");
          _builder.newLineIfNotEmpty();
        }
      }
      _builder.append("}");
      _builder.newLine();
      _builder.newLine();
      _builder.append("public boolean canCompare(PokerPattern o)");
      _builder.newLine();
      _builder.append("{");
      _builder.newLine();
      _builder.append("                ");
      _builder.append("if (o.getClass() != getClass())");
      _builder.newLine();
      _builder.append("                ");
      _builder.append("{");
      _builder.newLine();
      _builder.append("                \t");
      _builder.append("return false;");
      _builder.newLine();
      _builder.append("                ");
      _builder.append("}");
      _builder.newLine();
      _builder.append("                ");
      _builder.append("else");
      _builder.newLine();
      _builder.append("                ");
      _builder.append("{");
      _builder.newLine();
      _builder.append("                    ");
      _builder.append("return ");
      String _xblockexpression_1 = null;
      {
        final Function1<String, String> _function = new Function1<String, String>() {
          @Override
          public String apply(final String it) {
            return ((((it + " == ((") + patternName) + ")o).") + it);
          }
        };
        List<String> _map = ListExtensions.<String, String>map(assertEquals, _function);
        Vector<String> tmp = new Vector<String>(_map);
        tmp.add("true");
        _xblockexpression_1 = IterableExtensions.join(tmp, " && ");
      }
      _builder.append(_xblockexpression_1, "                    ");
      _builder.append(";");
      _builder.newLineIfNotEmpty();
      _builder.append("                ");
      _builder.append("}");
      _builder.newLine();
      _builder.append("}");
      _builder.newLine();
      sb.append(_builder);
      _xblockexpression = sb.toString();
    }
    return _xblockexpression;
  }
  
  public PokerPatternDetecterGenerator(final GeneratorSettings s) {
    this.settings = s;
  }
  
  public void run(final String patternName, final String description) {
    ReflectTreeBuilder.Node _root = this.ruleParser.getRoot(description);
    final ReflectTreeBuilder.PokerPattern root = ((ReflectTreeBuilder.PokerPattern) _root);
    String code = ((String) null);
    if (root.ellipsed) {
      String _matchTopTemplate = PokerPatternDetecterGenerator.matchTopTemplate(this.settings.gameName, patternName, "// TO-DO", "// TO-DO", "// TO-DO");
      code = _matchTopTemplate;
    } else {
      List<String> result = this.gen(patternName, root.pokerPatternExpression.assertEquals, root);
      String _get = result.get(0);
      String _get_1 = result.get(1);
      String _constructorTemplate = PokerPatternDetecterGenerator.constructorTemplate(patternName, root.pokerPatternExpression.assertEquals);
      String _plus = (_get_1 + _constructorTemplate);
      String _get_2 = result.get(2);
      String _matchTopTemplate_1 = PokerPatternDetecterGenerator.matchTopTemplate(this.settings.gameName, patternName, _get, _plus, _get_2);
      code = _matchTopTemplate_1;
    }
    final File dir = new File(((this.settings.genDir + this.settings.gameName) + "/patterns"));
    dir.mkdirs();
    File _file = new File(dir, (patternName + ".java"));
    FileUtils.saveString2File(_file, code);
  }
  
  /**
   * 得到各egroupList的matchi函数, 并合并出一个match函数体
   */
  public List<String> gen(final String patternName, final List<String> assertEquals, final ReflectTreeBuilder.PokerPattern node) {
    List<String> _xblockexpression = null;
    {
      int leastCards = Integer.MAX_VALUE;
      List<String> _xifexpression = null;
      if (node.ellipsed) {
        _xifexpression = Collections.<String>unmodifiableList(CollectionLiterals.<String>newArrayList("// TODO not implemented", ""));
      } else {
        List<String> _xblockexpression_1 = null;
        {
          int cnt = 0;
          String suffix = "";
          String body = "";
          for (final ReflectTreeBuilder.PokerPatternTerm pokerPatternTerm : node.pokerPatternExpression) {
            {
              String _body = body;
              StringConcatenation _builder = new StringConcatenation();
              _builder.append("List<Pair<PokerPattern, PokerCardGroup>> match");
              _builder.append(cnt, "");
              _builder.append(" = match");
              _builder.append(cnt, "");
              _builder.append("(pokerCardGroup, partial, first);");
              _builder.newLineIfNotEmpty();
              _builder.append("if (match");
              _builder.append(cnt, "");
              _builder.append(".size() > 0)");
              _builder.newLineIfNotEmpty();
              _builder.append("{");
              _builder.newLine();
              _builder.append("    ");
              _builder.append("return match");
              _builder.append(cnt, "    ");
              _builder.append(";");
              _builder.newLineIfNotEmpty();
              _builder.append("}");
              _builder.newLine();
              body = (_body + _builder);
              String[] result = this.gen(patternName, assertEquals, pokerPatternTerm);
              String _suffix = suffix;
              String _string = Integer.valueOf(cnt).toString();
              String _get = result[0];
              String _matchSubTemplate = PokerPatternDetecterGenerator.matchSubTemplate(_string, _get);
              suffix = (_suffix + _matchSubTemplate);
              String _get_1 = result[1];
              Integer _valueOf = Integer.valueOf(_get_1);
              int _min = Math.min(leastCards, (_valueOf).intValue());
              leastCards = _min;
              cnt++;
            }
          }
          String _string = Integer.valueOf(leastCards).toString();
          _xblockexpression_1 = Collections.<String>unmodifiableList(CollectionLiterals.<String>newArrayList(body, suffix, _string));
        }
        _xifexpression = _xblockexpression_1;
      }
      _xblockexpression = _xifexpression;
    }
    return _xblockexpression;
  }
  
  private final String TAG = "<<Tag>>";
  
  public String[] gen(final String patternName, final List<String> assertEquals, final ReflectTreeBuilder.PokerPatternTerm node) {
    String[] _xblockexpression = null;
    {
      int leastCards = 0;
      for (final ReflectTreeBuilder.PointWithColor p : node.pointsWithColor) {
        int _leastCards = leastCards;
        Integer _xtrycatchfinallyexpression = null;
        try {
          Integer _xblockexpression_1 = null;
          {
            int o1 = p.lQuantifier.inequality.ordinal();
            Integer _xifexpression = null;
            if ((o1 < 2)) {
              _xifexpression = Integer.valueOf(1);
            } else {
              Integer _xifexpression_1 = null;
              if ((o1 < 4)) {
                _xifexpression_1 = Integer.valueOf(p.lQuantifier.expression);
              } else {
                Integer _valueOf = Integer.valueOf(p.lQuantifier.expression);
                _xifexpression_1 = Integer.valueOf(((_valueOf).intValue() + 1));
              }
              _xifexpression = _xifexpression_1;
            }
            _xblockexpression_1 = _xifexpression;
          }
          _xtrycatchfinallyexpression = _xblockexpression_1;
        } catch (final Throwable _t) {
          if (_t instanceof Exception) {
            final Exception e = (Exception)_t;
            _xtrycatchfinallyexpression = Integer.valueOf(1);
          } else {
            throw Exceptions.sneakyThrow(_t);
          }
        }
        Integer _xtrycatchfinallyexpression_1 = null;
        try {
          Integer _xblockexpression_2 = null;
          {
            int o2 = p.rQuantifier.inequality.ordinal();
            Integer _xifexpression = null;
            if ((o2 < 2)) {
              _xifexpression = Integer.valueOf(1);
            } else {
              Integer _xifexpression_1 = null;
              if ((o2 < 4)) {
                _xifexpression_1 = Integer.valueOf(p.rQuantifier.expression);
              } else {
                Integer _valueOf = Integer.valueOf(p.rQuantifier.expression);
                _xifexpression_1 = Integer.valueOf(((_valueOf).intValue() + 1));
              }
              _xifexpression = _xifexpression_1;
            }
            _xblockexpression_2 = _xifexpression;
          }
          _xtrycatchfinallyexpression_1 = _xblockexpression_2;
        } catch (final Throwable _t_1) {
          if (_t_1 instanceof Exception) {
            final Exception e2 = (Exception)_t_1;
            _xtrycatchfinallyexpression_1 = Integer.valueOf(1);
          } else {
            throw Exceptions.sneakyThrow(_t_1);
          }
        }
        int _multiply = ((_xtrycatchfinallyexpression).intValue() * (_xtrycatchfinallyexpression_1).intValue());
        leastCards = (_leastCards + _multiply);
      }
      int depth = 0;
      String body = this.TAG;
      LinkedList<Integer> fixedPoint = new LinkedList<Integer>();
      LinkedList<Integer> fixedColor = new LinkedList<Integer>();
      for (final ReflectTreeBuilder.PointWithColor pointWithColor : node.pointsWithColor) {
        {
          int _plusPlus = depth++;
          String result = this.gen(pointWithColor, _plusPlus, fixedPoint, fixedColor);
          String _replace = body.replace(this.TAG, result);
          body = _replace;
        }
      }
      StringConcatenation _builder = new StringConcatenation();
      _builder.append("if (partial || (tmp.size() == 0))");
      _builder.newLine();
      _builder.append("{");
      _builder.newLine();
      _builder.append("    ");
      _builder.append("result.add(new Pair<PokerPattern, PokerCardGroup>(new ");
      _builder.append(patternName, "    ");
      _builder.append("(game,");
      {
        for(final String e_1 : assertEquals) {
          _builder.append(e_1, "    ");
          _builder.append(", ");
        }
      }
      _builder.append(" searchStack.peek().size() - tmp.size(), Arrays.asList(");
      Object _xifexpression = null;
      boolean _notEquals = (!Objects.equal(node.weightExpressions, null));
      if (_notEquals) {
        _xifexpression = IterableExtensions.join(node.weightExpressions, ",");
      } else {
        _xifexpression = Integer.valueOf(1);
      }
      _builder.append(_xifexpression, "    ");
      _builder.append(")), tmp));");
      _builder.newLineIfNotEmpty();
      _builder.append("    ");
      _builder.newLine();
      _builder.append("    ");
      _builder.append("if (first)");
      _builder.newLine();
      _builder.append("    ");
      _builder.append("{");
      _builder.newLine();
      _builder.append("        ");
      _builder.append("return result;");
      _builder.newLine();
      _builder.append("    ");
      _builder.append("}");
      _builder.newLine();
      _builder.append("}");
      _builder.newLine();
      String _replace = body.replace(this.TAG, _builder);
      body = _replace;
      String _string = Integer.valueOf(leastCards).toString();
      _xblockexpression = new String[] { body, _string };
    }
    return _xblockexpression;
  }
  
  private final static char ValBase = '0';
  
  private final static char ColorBase = 'A';
  
  private final static char PointBase = 'a';
  
  public String gen(final ReflectTreeBuilder.PointWithColor node, final int depth, final LinkedList<Integer> fixedPoint, final LinkedList<Integer> fixedColor) {
    String _xblockexpression = null;
    {
      StringConcatenation _builder = new StringConcatenation();
      _builder.append("searchStack.push(tmp);");
      _builder.newLine();
      _builder.append(this.TAG, "");
      _builder.newLineIfNotEmpty();
      _builder.append("searchStack.pop();");
      String result = _builder.toString();
      boolean needNext = false;
      boolean _equals = Objects.equal(node.lQuantifier, null);
      if (_equals) {
        StringConcatenation _builder_1 = new StringConcatenation();
        _builder_1.append("final int l");
        String _string = Integer.valueOf(depth).toString();
        _builder_1.append(_string, "");
        _builder_1.append(" = 1;");
        _builder_1.newLineIfNotEmpty();
        _builder_1.append("\t\t\t\t");
        _builder_1.append(this.TAG, "\t\t\t\t");
        String _replace = result.replace(this.TAG, _builder_1);
        result = _replace;
      } else {
        boolean _or = false;
        boolean _equals_1 = Objects.equal(node.lQuantifier.inequality, null);
        if (_equals_1) {
          _or = true;
        } else {
          boolean _equals_2 = Objects.equal(node.lQuantifier.inequality, ReflectTreeBuilder.Inequality.E);
          _or = _equals_2;
        }
        if (_or) {
          StringConcatenation _builder_2 = new StringConcatenation();
          _builder_2.append("final int l");
          _builder_2.append(depth, "");
          _builder_2.append(" = ");
          _builder_2.append(node.lQuantifier.expression, "");
          _builder_2.append(";");
          _builder_2.newLineIfNotEmpty();
          _builder_2.append("\t\t\t\t");
          _builder_2.append(this.TAG, "\t\t\t\t");
          _builder_2.newLineIfNotEmpty();
          String _replace_1 = result.replace(this.TAG, _builder_2);
          result = _replace_1;
        } else {
          int _ordinal = node.lQuantifier.inequality.ordinal();
          final boolean ll = (_ordinal < 2);
          needNext = true;
          StringConcatenation _builder_3 = new StringConcatenation();
          _builder_3.append("for (int l");
          _builder_3.append(depth, "");
          _builder_3.append(" = ");
          Object _xifexpression = null;
          if (ll) {
            _xifexpression = Integer.valueOf(1);
          } else {
            String _xifexpression_1 = null;
            boolean _equals_3 = Objects.equal(node.lQuantifier.inequality, ReflectTreeBuilder.Inequality.G);
            if (_equals_3) {
              _xifexpression_1 = "+1";
            } else {
              _xifexpression_1 = "";
            }
            _xifexpression = (node.lQuantifier.expression + _xifexpression_1);
          }
          _builder_3.append(_xifexpression, "");
          _builder_3.append(";next");
          _builder_3.append(depth, "");
          _builder_3.append(" ");
          _builder_3.newLineIfNotEmpty();
          CharSequence _xifexpression_2 = null;
          if (ll) {
            StringConcatenation _builder_4 = new StringConcatenation();
            _builder_4.append(" ");
            _builder_4.append("&& l");
            _builder_4.append(depth, " ");
            _builder_4.append(" ");
            String _string_1 = node.lQuantifier.inequality.toString();
            _builder_4.append(_string_1, " ");
            _builder_4.append(" ");
            _builder_4.append(node.lQuantifier.expression, " ");
            _xifexpression_2 = _builder_4;
          } else {
            _xifexpression_2 = "";
          }
          _builder_3.append(_xifexpression_2, "");
          _builder_3.append(";l");
          _builder_3.append(depth, "");
          _builder_3.append("++)");
          _builder_3.newLineIfNotEmpty();
          _builder_3.append("{");
          _builder_3.newLine();
          _builder_3.append("\t");
          _builder_3.append(this.TAG, "\t");
          _builder_3.newLineIfNotEmpty();
          _builder_3.append("} ");
          String _replace_2 = result.replace(this.TAG, _builder_3);
          result = _replace_2;
        }
      }
      boolean _equals_4 = Objects.equal(node.rQuantifier, null);
      if (_equals_4) {
        String _replace_3 = result.replace(this.TAG, ((("final int r" + Integer.valueOf(depth)) + "= 1;") + this.TAG));
        result = _replace_3;
      } else {
        boolean _or_1 = false;
        boolean _equals_5 = Objects.equal(node.rQuantifier.inequality, null);
        if (_equals_5) {
          _or_1 = true;
        } else {
          boolean _equals_6 = Objects.equal(node.rQuantifier.inequality, ReflectTreeBuilder.Inequality.E);
          _or_1 = _equals_6;
        }
        if (_or_1) {
          StringConcatenation _builder_5 = new StringConcatenation();
          _builder_5.append("final int r");
          _builder_5.append(depth, "");
          _builder_5.append(" = ");
          _builder_5.append(node.rQuantifier.expression, "");
          _builder_5.append(";");
          _builder_5.newLineIfNotEmpty();
          _builder_5.append("\t\t\t\t");
          _builder_5.append(this.TAG, "\t\t\t\t");
          String _replace_4 = result.replace(this.TAG, _builder_5);
          result = _replace_4;
        } else {
          int _ordinal_1 = node.rQuantifier.inequality.ordinal();
          final boolean rl = (_ordinal_1 < 2);
          needNext = true;
          StringConcatenation _builder_6 = new StringConcatenation();
          _builder_6.append("for (int r");
          _builder_6.append(depth, "");
          _builder_6.append(" = ");
          Object _xifexpression_3 = null;
          if (rl) {
            _xifexpression_3 = Integer.valueOf(1);
          } else {
            String _xifexpression_4 = null;
            boolean _equals_7 = Objects.equal(node.rQuantifier.inequality, ReflectTreeBuilder.Inequality.G);
            if (_equals_7) {
              _xifexpression_4 = "+1";
            } else {
              _xifexpression_4 = "";
            }
            _xifexpression_3 = (node.rQuantifier.expression + _xifexpression_4);
          }
          _builder_6.append(_xifexpression_3, "");
          _builder_6.append(";next");
          _builder_6.append(depth, "");
          _builder_6.append(" ");
          CharSequence _xifexpression_5 = null;
          if (rl) {
            StringConcatenation _builder_7 = new StringConcatenation();
            _builder_7.append(" ");
            _builder_7.append("&& r");
            _builder_7.append(depth, " ");
            _builder_7.append(" ");
            String _string_2 = node.rQuantifier.inequality.toString();
            _builder_7.append(_string_2, " ");
            _builder_7.append(" ");
            _builder_7.append(node.rQuantifier.expression, " ");
            _xifexpression_5 = _builder_7;
          } else {
            _xifexpression_5 = "";
          }
          _builder_6.append(_xifexpression_5, "");
          _builder_6.append(";r");
          _builder_6.append(depth, "");
          _builder_6.append("++)");
          _builder_6.newLineIfNotEmpty();
          _builder_6.append("{");
          _builder_6.newLine();
          _builder_6.append("\t");
          _builder_6.append(this.TAG, "\t");
          _builder_6.newLineIfNotEmpty();
          _builder_6.append("} ");
          String _replace_5 = result.replace(this.TAG, _builder_6);
          result = _replace_5;
        }
      }
      if (needNext) {
        StringConcatenation _builder_8 = new StringConcatenation();
        _builder_8.append("boolean next");
        _builder_8.append(depth, "");
        _builder_8.append("=true;");
        _builder_8.newLineIfNotEmpty();
        StringConcatenation _builder_9 = new StringConcatenation();
        _builder_9.append("next");
        _builder_9.append(depth, "");
        _builder_9.append(" = false; ");
        _builder_9.newLineIfNotEmpty();
        _builder_9.append(this.TAG, "");
        String _replace_6 = result.replace(this.TAG, _builder_9);
        String _plus = (_builder_8.toString() + _replace_6);
        result = _plus;
      }
      String colorExpression = ((String) null);
      String pointExpression = ((String) null);
      boolean _notEquals = (!Objects.equal(node.color, null));
      if (_notEquals) {
        boolean _and = false;
        if (!node.color.isSome) {
          _and = false;
        } else {
          _and = (!node.color.not);
        }
        if (_and) {
          StringConcatenation _builder_10 = new StringConcatenation();
          _builder_10.append("settings.someColors.get(\'");
          _builder_10.append(((char) (PokerPatternDetecterGenerator.ColorBase + node.color.index)), "");
          _builder_10.append("\' - \'A\')");
          colorExpression = _builder_10.toString();
        } else {
          if (node.color.isVal) {
            StringConcatenation _builder_11 = new StringConcatenation();
            _builder_11.append("Color.get(");
            _builder_11.append(node.color.index, "");
            _builder_11.append(")");
            colorExpression = _builder_11.toString();
          } else {
            String _xifexpression_6 = null;
            if (node.color.not) {
              StringConcatenation _builder_12 = new StringConcatenation();
              _builder_12.append("someColor");
              _builder_12.append(depth, "");
              _xifexpression_6 = _builder_12.toString();
            } else {
              StringConcatenation _builder_13 = new StringConcatenation();
              _builder_13.append(((char) (PokerPatternDetecterGenerator.ColorBase + node.color.index)), "");
              _xifexpression_6 = _builder_13.toString();
            }
            colorExpression = _xifexpression_6;
            boolean _or_2 = false;
            if (node.color.not) {
              _or_2 = true;
            } else {
              boolean _contains = fixedColor.contains(Integer.valueOf(node.color.index));
              boolean _not = (!_contains);
              _or_2 = _not;
            }
            if (_or_2) {
              fixedColor.add(Integer.valueOf(node.color.index));
              StringConcatenation _builder_14 = new StringConcatenation();
              _builder_14.append("for (Color ");
              _builder_14.append(colorExpression, "");
              _builder_14.append(" : Color.values())");
              _builder_14.newLineIfNotEmpty();
              _builder_14.append("{");
              _builder_14.newLine();
              _builder_14.append("\t");
              CharSequence _xifexpression_7 = null;
              if (node.color.not) {
                StringConcatenation _builder_15 = new StringConcatenation();
                _builder_15.append("if(");
                _builder_15.append(colorExpression, "");
                _builder_15.append(" == settings.someColors.get(\'");
                _builder_15.append(((char) (PokerPatternDetecterGenerator.ColorBase + node.color.index)), "");
                _builder_15.append("\'-\'A\')) ");
                _builder_15.newLineIfNotEmpty();
                _builder_15.append("\t");
                _builder_15.append("continue;");
                _builder_15.newLine();
                _xifexpression_7 = _builder_15;
              }
              _builder_14.append(_xifexpression_7, "\t");
              _builder_14.newLineIfNotEmpty();
              _builder_14.append("\t");
              _builder_14.append(this.TAG, "\t");
              _builder_14.newLineIfNotEmpty();
              _builder_14.append("}");
              _builder_14.newLine();
              String _replace_7 = result.replace(this.TAG, _builder_14);
              result = _replace_7;
            }
          }
        }
      } else {
        colorExpression = "null";
      }
      ReflectTreeBuilder.PointBound lowerBound = ((ReflectTreeBuilder.PointBound) null);
      ReflectTreeBuilder.PointBound higherBound = ((ReflectTreeBuilder.PointBound) null);
      if (node.point.isAny) {
        pointExpression = "0";
      } else {
        boolean _and_1 = false;
        if (!node.point.isSome) {
          _and_1 = false;
        } else {
          _and_1 = (!node.point.not);
        }
        if (_and_1) {
          StringConcatenation _builder_16 = new StringConcatenation();
          _builder_16.append("settings.somePoints.get(\'");
          _builder_16.append(((char) (PokerPatternDetecterGenerator.PointBase + node.color.index)), "");
          _builder_16.append("\' - \'a\')");
          pointExpression = _builder_16.toString();
        } else {
          if (node.point.isVal) {
            String _string_3 = Integer.valueOf(node.point.index).toString();
            pointExpression = _string_3;
          } else {
            String _xifexpression_8 = null;
            if (node.point.not) {
              StringConcatenation _builder_17 = new StringConcatenation();
              _builder_17.append("somePoint");
              _builder_17.append(depth, "");
              _xifexpression_8 = _builder_17.toString();
            } else {
              StringConcatenation _builder_18 = new StringConcatenation();
              _builder_18.append(((char) (PokerPatternDetecterGenerator.PointBase + node.point.index)), "");
              _xifexpression_8 = _builder_18.toString();
            }
            pointExpression = _xifexpression_8;
            boolean _or_3 = false;
            if (node.point.not) {
              _or_3 = true;
            } else {
              boolean _contains_1 = fixedPoint.contains(Integer.valueOf(node.point.index));
              boolean _not_1 = (!_contains_1);
              _or_3 = _not_1;
            }
            if (_or_3) {
              boolean _notEquals_1 = (!Objects.equal(node.point.pointBounds, null));
              if (_notEquals_1) {
                for (final ReflectTreeBuilder.PointBound b : node.point.pointBounds) {
                  {
                    boolean _and_2 = false;
                    boolean _equals_8 = Objects.equal(higherBound, null);
                    if (!_equals_8) {
                      _and_2 = false;
                    } else {
                      int _ordinal_2 = b.inequality.ordinal();
                      boolean _lessEqualsThan = (_ordinal_2 <= 2);
                      _and_2 = _lessEqualsThan;
                    }
                    if (_and_2) {
                      higherBound = b;
                    }
                    boolean _and_3 = false;
                    boolean _equals_9 = Objects.equal(lowerBound, null);
                    if (!_equals_9) {
                      _and_3 = false;
                    } else {
                      int _ordinal_3 = b.inequality.ordinal();
                      boolean _greaterEqualsThan = (_ordinal_3 >= 2);
                      _and_3 = _greaterEqualsThan;
                    }
                    if (_and_3) {
                      lowerBound = b;
                    }
                  }
                }
              }
              String _xifexpression_9 = null;
              boolean _notEquals_2 = (!Objects.equal(higherBound, null));
              if (_notEquals_2) {
                String _xifexpression_10 = null;
                if (higherBound.isVal) {
                  _xifexpression_10 = Character.valueOf(((char) (PokerPatternDetecterGenerator.ValBase + higherBound.index))).toString();
                } else {
                  String _xifexpression_11 = null;
                  if (higherBound.isVar) {
                    _xifexpression_11 = Character.valueOf(((char) (PokerPatternDetecterGenerator.PointBase + higherBound.index))).toString();
                  } else {
                    StringConcatenation _builder_19 = new StringConcatenation();
                    _builder_19.append("settings.somePoints.get(\'");
                    _builder_19.append(((char) (PokerPatternDetecterGenerator.PointBase + higherBound.index)), "");
                    _builder_19.append("\'-\'a\'))");
                    _xifexpression_11 = _builder_19.toString();
                  }
                  _xifexpression_10 = _xifexpression_11;
                }
                _xifexpression_9 = _xifexpression_10;
              } else {
                _xifexpression_9 = "";
              }
              String hb = _xifexpression_9;
              StringConcatenation _builder_20 = new StringConcatenation();
              _builder_20.append("Vector<Integer> toBeScanned");
              _builder_20.append(depth, "");
              _builder_20.append(" = settings.getScanList(");
              String _string_4 = Boolean.valueOf(node.byOrder).toString();
              _builder_20.append(_string_4, "");
              _builder_20.append(");");
              _builder_20.newLineIfNotEmpty();
              _builder_20.append("int highIndex");
              _builder_20.append(depth, "");
              _builder_20.append(" = ");
              {
                boolean _equals_8 = Objects.equal(higherBound, null);
                if (_equals_8) {
                  _builder_20.append(" toBeScanned");
                  _builder_20.append(depth, "");
                  _builder_20.append(".size()-1 ");
                } else {
                  _builder_20.append("toBeScanned");
                  _builder_20.append(depth, "");
                  _builder_20.append(".lastIndexOf(");
                  _builder_20.append(higherBound.index, "");
                  _builder_20.append(")");
                  {
                    boolean _equals_9 = Objects.equal(higherBound.inequality, ReflectTreeBuilder.Inequality.L);
                    if (_equals_9) {
                      _builder_20.append(" -1 ");
                    }
                  }
                }
              }
              _builder_20.append(";");
              _builder_20.newLineIfNotEmpty();
              _builder_20.newLine();
              _builder_20.append("for (int index");
              _builder_20.append(depth, "");
              _builder_20.append(" = ");
              {
                boolean _equals_10 = Objects.equal(lowerBound, null);
                if (_equals_10) {
                  _builder_20.append(" 0 ");
                } else {
                  _builder_20.append("toBeScanned");
                  _builder_20.append(depth, "");
                  _builder_20.append(".indexOf(");
                  _builder_20.append(lowerBound.index, "");
                  _builder_20.append(")");
                  {
                    boolean _equals_11 = Objects.equal(lowerBound.inequality, ReflectTreeBuilder.Inequality.G);
                    if (_equals_11) {
                      _builder_20.append(" +1 ");
                    }
                  }
                }
              }
              _builder_20.append("; index");
              _builder_20.append(depth, "");
              _builder_20.append(" <= highIndex");
              _builder_20.append(depth, "");
              _builder_20.append(" +1 -r");
              _builder_20.append(depth, "");
              _builder_20.append("; index");
              _builder_20.append(depth, "");
              _builder_20.append("++)");
              _builder_20.newLineIfNotEmpty();
              _builder_20.append("{");
              _builder_20.newLine();
              _builder_20.append("\t");
              _builder_20.append("int ");
              _builder_20.append(pointExpression, "\t");
              _builder_20.append(" = toBeScanned");
              _builder_20.append(depth, "\t");
              _builder_20.append(".get(index");
              _builder_20.append(depth, "\t");
              _builder_20.append(");");
              _builder_20.newLineIfNotEmpty();
              _builder_20.append("\t");
              CharSequence _xifexpression_12 = null;
              if (node.point.not) {
                StringConcatenation _builder_21 = new StringConcatenation();
                _builder_21.append("if(somePoint");
                _builder_21.append(depth, "");
                _builder_21.append(" == settings.somePoints.get(\'");
                _builder_21.append(((char) (PokerPatternDetecterGenerator.PointBase + node.point.index)), "");
                _builder_21.append("\'-\'a\')) ");
                _builder_21.newLineIfNotEmpty();
                _builder_21.append("\t");
                _builder_21.append("continue;");
                _builder_21.newLine();
                _xifexpression_12 = _builder_21;
              }
              _builder_20.append(_xifexpression_12, "\t");
              _builder_20.newLineIfNotEmpty();
              _builder_20.append("\t");
              _builder_20.append(this.TAG, "\t");
              _builder_20.newLineIfNotEmpty();
              _builder_20.append("}");
              _builder_20.newLine();
              String _replace_8 = result.replace(this.TAG, _builder_20);
              result = _replace_8;
            }
          }
        }
      }
      StringConcatenation _builder_22 = new StringConcatenation();
      _builder_22.append("tmp = searchStack.peek().contains(l");
      _builder_22.append(depth, "");
      _builder_22.append(", ");
      _builder_22.append(pointExpression, "");
      _builder_22.append(", ");
      _builder_22.append(colorExpression, "");
      _builder_22.append(", ");
      String _string_5 = Boolean.valueOf(node.byOrder).toString();
      _builder_22.append(_string_5, "");
      _builder_22.append(", r");
      _builder_22.append(depth, "");
      _builder_22.append(", ");
      {
        boolean _notEquals_3 = (!Objects.equal(lowerBound, null));
        if (_notEquals_3) {
          _builder_22.append(lowerBound.index, "");
        } else {
          _builder_22.append("-1");
        }
      }
      _builder_22.append(", ");
      {
        boolean _notEquals_4 = (!Objects.equal(higherBound, null));
        if (_notEquals_4) {
          _builder_22.append(higherBound.index, "");
        } else {
          _builder_22.append("-1");
        }
      }
      _builder_22.append(");");
      _builder_22.newLineIfNotEmpty();
      _builder_22.newLine();
      _builder_22.append("if (tmp != null)");
      _builder_22.newLine();
      _builder_22.append("{");
      _builder_22.newLine();
      _builder_22.append("    ");
      CharSequence _xifexpression_13 = null;
      if (needNext) {
        StringConcatenation _builder_23 = new StringConcatenation();
        _builder_23.append("next");
        _builder_23.append(depth, "");
        _builder_23.append(" = true;");
        _xifexpression_13 = _builder_23;
      }
      _builder_22.append(_xifexpression_13, "    ");
      _builder_22.newLineIfNotEmpty();
      _builder_22.append("    ");
      _builder_22.newLine();
      _builder_22.append("    ");
      CharSequence _xifexpression_14 = null;
      boolean _and_2 = false;
      boolean _notEquals_5 = (!Objects.equal(node.lQuantifier, null));
      if (!_notEquals_5) {
        _and_2 = false;
      } else {
        _and_2 = (node.lQuantifier.catchId > 0);
      }
      if (_and_2) {
        StringConcatenation _builder_24 = new StringConcatenation();
        _builder_24.append("int _");
        _builder_24.append(node.lQuantifier.catchId, "");
        _builder_24.append(" = l");
        _builder_24.append(depth, "");
        _builder_24.append(";");
        _xifexpression_14 = _builder_24;
      }
      _builder_22.append(_xifexpression_14, "    ");
      _builder_22.newLineIfNotEmpty();
      _builder_22.append("    ");
      CharSequence _xifexpression_15 = null;
      boolean _and_3 = false;
      boolean _notEquals_6 = (!Objects.equal(node.rQuantifier, null));
      if (!_notEquals_6) {
        _and_3 = false;
      } else {
        _and_3 = (node.rQuantifier.catchId > 0);
      }
      if (_and_3) {
        StringConcatenation _builder_25 = new StringConcatenation();
        _builder_25.append("int _");
        _builder_25.append(node.rQuantifier.catchId, "");
        _builder_25.append(" = r");
        _builder_25.append(depth, "");
        _builder_25.append(";");
        _xifexpression_15 = _builder_25;
      }
      _builder_22.append(_xifexpression_15, "    ");
      _builder_22.newLineIfNotEmpty();
      _builder_22.append("    ");
      _builder_22.newLine();
      _builder_22.append("    ");
      _builder_22.append(this.TAG, "    ");
      _builder_22.newLineIfNotEmpty();
      _builder_22.append("}");
      _builder_22.newLine();
      String _replace_9 = result.replace(
        this.TAG, _builder_22);
      result = _replace_9;
      _xblockexpression = result;
    }
    return _xblockexpression;
  }
}
